package com.example.baiguangsystem.constroller;

import com.example.baiguangsystem.entity.LoginStatusEnum;
import com.example.baiguangsystem.entity.Paging;
import com.example.baiguangsystem.entity.User;
import com.example.baiguangsystem.service.UserService;
import com.example.baiguangsystem.vo.ResultType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.net.http.HttpResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;

/**
 * 用户功能控制器类
 *
 * @Author: 27641
 * @ProjectName: BaiGuangSystem
 * @Date: 2022/02/02/23:12
 * @noinspection SpellCheckingInspection
 */
@Controller
@RequestMapping("/user")
public class UserController {

    /**
     * 依赖注入
     */
    @Autowired
    private UserService userService;

    /**
     * 用户登录功能
     *
     * @param user         输入的用户信息包装对象
     * @param session      用于存储的域对象
     * @param httpResponse 用于登录成功之后发送cookie给客户端
     * @return 登录结果
     */
    @PostMapping("/login")
    @ResponseBody
    public ResultType login(@RequestBody User user, HttpSession session, HttpServletResponse httpResponse) {
        LoginStatusEnum login = this.userService.login(user, session, httpResponse);
        if (login == LoginStatusEnum.LOGIN_SUCCESS) {
            return ResultType.success("登录成功！", user);
        }
        if (login == LoginStatusEnum.NOT_USER) {
            return ResultType.fail("登录失败，没有该用户！");
        }
        if (login == LoginStatusEnum.USER_OR_PASSWORD_ERROR) {
            return ResultType.fail("登录失败,账号或者密码错误！");
        }
        return ResultType.fail("登录失败，未知错误！");
    }

    /**
     * 注销用户功能
     *
     * @param session  session域对象
     * @param response 响应对象
     * @param request  请求对象
     * @return ResultType 返回封装结果对象
     */
    @GetMapping("/logout")
    @ResponseBody
    public ResultType logout(HttpSession session, HttpServletResponse response, HttpServletRequest request) {
        this.userService.logoutUser(session, request, response);
        return ResultType.success("注销成功！");
    }

    /**
     * 新增用户业务实现
     *
     * @param user 需要新增的用户封装
     * @return 操作结果封装
     */
    @PostMapping("/addNewUser")
    @ResponseBody
    public ResultType addNewUser(@RequestBody User user) {
        System.out.println(user);
        if (this.userService.addNewUser(user)) {
            return ResultType.success("新增用户成功！");
        }
        return ResultType.fail("新增用户失败!");
    }

    /**
     * 查询用户信息
     *
     * @param session session域对象
     * @param request 请求参数对象
     * @return 查询结果
     */
    @GetMapping("/selectUserById")
    @ResponseBody
    public ResultType selectUserById(HttpSession session, HttpServletRequest request) {
        User user = this.userService.selectUserMessagesById(session, request);
        if (user == null) {
            return ResultType.fail("查询用户信息失败！");
        }
        return ResultType.success("查询用户信息成功", user);
    }

    /**
     * 查询所有用户的信息，需要超级管理员root用户才可以进行访问
     *
     * @return 所有用户信息
     */
    @GetMapping("/findAllUser")
    @ResponseBody
    public ResultType findUserAll() {
        List<User> userAll = this.userService.findUserAll();
        if (userAll != null && userAll.size() > 0) {
            return ResultType.success("查找所有用户成功！", userAll);
        }
        return ResultType.fail("查找失败！");
    }

    /**
     * 查询所有用户（root）,（分页）
     *
     * @param paging 查询要求封装
     * @return 查询结果
     */
    @PostMapping("/findAllUserByLimit")
    @ResponseBody
    public ResultType findAllUserByLimit(@RequestBody Paging paging) {
        List<User> userAllLimit = this.userService.findUserAllLimit(paging);
        if (userAllLimit != null && userAllLimit.size() != 0) {
            return ResultType.success("查询成功！", userAllLimit);
        }
        return ResultType.fail("查询失败，可能是因为查询页数比总页数更高，也可能是因为查询结果为null！");
    }

    /**
     * （测试）post的每一次请求是否都是同一个session对象。
     * [结论]是同一个session对象。
     *
     * @param session session域对象
     * @param request 参数对象
     * @return 操作结果
     */
    @GetMapping("/sessionTest")
    @ResponseBody
    public ResultType sessionTest(HttpServletRequest request, HttpSession session) {
        Cookie[] cookies = request.getCookies();
        List<User> list = new ArrayList<>();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                User user = (User) session.getAttribute(cookie.getName());
                if (user != null) {
                    return ResultType.success("查询成功！", user);
                }
            }
        }
        return ResultType.fail("查询失败！");
    }

    /**
     * （测试）用于查看所以cookie
     *
     * @param servletRequest 请求参数
     * @return 操作结果封装对象
     */
    @RequestMapping(value = "/findCookieTest", method = RequestMethod.GET)
    @ResponseBody
    public ResultType selectCookiesTest(HttpServletRequest servletRequest) {
        Cookie[] cookies = servletRequest.getCookies();
        if (cookies != null) {
            return ResultType.success("查询到该客户端存在cookie", cookies);
        }
        return ResultType.fail("该客户端没有任何cookie...");
    }

    /**
     * （测试）实验如果没有cookie的情况下，request的getCookie方法是否会是null
     * 结论：如果是没有cookie的情况，getCookies返回的是null
     *
     * @param request 请求对象
     */
    @GetMapping("/testCookiesIsNull")
    public void cookieIsNullTest(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        System.out.println(cookies != null);
    }


    /**
     * （测试）是否将用户存储进去了session域之中
     *
     * @param session session域对象
     * @param request 请求对象
     * @return 操作结果
     */
    @GetMapping("/checkSessionTest")
    @ResponseBody
    public ResultType checkSessionTest(HttpSession session, HttpServletRequest request) {
        Enumeration<String> attributeNames = session.getAttributeNames();
        List<Object> list = new ArrayList<>();
        while (attributeNames.hasMoreElements()) {
            String element = attributeNames.nextElement();
            list.add(session.getAttribute(element));
        }
        for (Object o : list) {
            System.out.println(o);
        }
        return ResultType.success(list);
    }
}
